/*
 * Copyright (c) 2016 zhangcm. All Rights Reserved.
 */
package com.deram.ctin.dependencies.serv.mybatis;

import com.baomidou.mybatisplus.entity.TableFieldInfo;
import com.baomidou.mybatisplus.entity.TableInfo;
import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.mapper.AutoSqlInjector;
import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;

import java.util.List;

/**
 * @author zhangcm
 * @version 1.0, 2017/9/28
 */
public class MybatisInjector extends AutoSqlInjector {

    @Override
    public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
        this.injectBatchInsertSql("batchInsert", mapperClass, modelClass, table);
        this.injectSelectOneByWrapperSql("selectOneByWrapper", mapperClass, modelClass, table);
    }

    protected void injectSelectOneByWrapperSql(String method, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
        String formatSql = "<script>SELECT %s FROM %s %s</script>";
        String sql = String.format(formatSql, sqlSelectColumns(table, true), table.getTableName(), sqlWhereEntityWrapper(table));
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        this.addSelectMappedStatement(mapperClass, method, sqlSource, modelClass, table);
    }

    protected void injectBatchInsertSql(String method, Class<?> mapperClass, Class<?> modelClass, TableInfo table){
        MybatisKey key = getMybatisKey(method, table);
        List<String> nameList = Lists.newArrayList();
        List<String> valueList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(table.getKeyProperty()) && table.getIdType() != IdType.AUTO){
            nameList.add(table.getKeyColumn());
            valueList.add(table.getKeyProperty());
        }
        for (int i = 0; i < table.getFieldList().size(); i++) {
            TableFieldInfo fieldInfo = table.getFieldList().get(i);
            nameList.add(fieldInfo.getColumn());
            valueList.add("#{item." + fieldInfo.getEl() + "}");
        }
        String formatSql = "<script>insert into %s(%s) values<foreach collection=\"list\" item=\"item\" separator=\",\" >(%s)</foreach></script>";
        String sql = String.format(formatSql, table.getTableName(), StringUtils.join(nameList, ","), StringUtils.join(valueList, ","));
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        this.addInsertMappedStatement(mapperClass, modelClass, method, sqlSource, key.getGenerator(), key.getProperty(), key.getColumn());
    }

    protected MybatisKey getMybatisKey(String method, TableInfo table){
        MybatisKey result = new MybatisKey();
        if (StringUtils.isNotEmpty(table.getKeyProperty()) && table.getIdType() == IdType.AUTO) {
            result.setGenerator(new Jdbc3KeyGenerator());
            result.setProperty(table.getKeyProperty());
            result.setColumn(table.getKeyColumn());
        } else if (StringUtils.isNotEmpty(table.getKeyProperty()) && null != table.getKeySequence()) {
            result.setGenerator(TableInfoHelper.genKeyGenerator(table, builderAssistant, method, languageDriver));
            result.setProperty(table.getKeyProperty());
            result.setColumn(table.getKeyColumn());
        }
        return result;
    }
}
